package cn.kerui.manage.service.manageuser.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ReUtil;
import cn.kerui.common.enums.AuthExceptionMsg;
import cn.kerui.common.exception.BaseException;
import cn.kerui.common.exception.ServiceException;
import cn.kerui.common.framework.util.crypto.EncipherUtil;
import cn.kerui.common.framework.util.crypto.provider.EncipherProvider;
import cn.kerui.common.framework.util.lang.CollectionUtil;
import cn.kerui.common.framework.util.lang.ObjectUtil;
import cn.kerui.common.helper.RequestHelper;
import cn.kerui.manage.service.manageuser.ManageUserService;
import cn.kerui.manage.vo.manageuser.CreateUserModel;
import cn.kerui.manage.vo.manageuser.UserInfoVo;
import cn.kerui.repos.entities.manage.ManageUserLogin;
import cn.kerui.repos.entities.manageuser.ManageUserInfo;
import cn.kerui.repos.mapper.manage.ManageRoleMapper;
import cn.kerui.repos.mapper.manage.ManageUserLoginMapper;
import cn.kerui.repos.mapper.manageuser.ManageUserInfoMapper;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 管理端用户业务实现层
 * </p>
 * <p>
 * 创建于 2023/11/23 14:29
 * </p>
 *
 * @author yangkai
 * @version v1.0
 * @since 1.0.0
 */
@Service
@Slf4j
@AllArgsConstructor
public class ManageUserServiceImpl implements ManageUserService {

    private ManageUserLoginMapper userLoginMapper;

    private ManageUserInfoMapper manageUserInfoMapper;

    private ManageRoleMapper manageRoleMapper;


    private RedisTemplate redisTemplate;



    /**
     * 密码强度规则匹配正则表达式（密码强度校验，最少6位，是否包含至少一个小写字母、一个大写字母和一个数字）
     */
    private static final String PASSWORD_RULE = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z\\d]{6,16}$";

    /**
     * 创建用户
     *
     * @param model
     */
    @Override
    public void createUser(CreateUserModel model) {
        final String password = model.getPassword();

        Assert.isTrue(ReUtil.isMatch(PASSWORD_RULE, password), () -> new BaseException("密码格式不正确，请重新输入"));

        final String username = model.getUsername();

        LambdaQueryWrapper<ManageUserLogin> queryWrapper =
            Wrappers.query(ManageUserLogin.class).lambda().eq(ManageUserLogin::getUserName, username);

        boolean exists = userLoginMapper.exists(queryWrapper);

        Assert.isFalse(exists, () -> new BaseException("该用户名已存在"));

        EncipherProvider encipherProvider = EncipherUtil.encipherGenerateSalt(password);
        ManageUserLogin build = ManageUserLogin.builder()
                .userName(username)
                .password(encipherProvider.getEncipherPass())
                .salt(encipherProvider.getSalt())
                .phone(model.getPhone()).build();

        userLoginMapper.insert(build);

        log.info("创建用户成功, user = {}", JSON.toJSONString(build));
    }



    @Override
    public UserInfoVo getUserInfo(Long userId) {
        UserInfoVo userInfoVo = new UserInfoVo();

        ManageUserInfo manageUserInfo = manageUserInfoMapper.selectById(userId);
        if (ObjectUtil.isEmpty(manageUserInfo)) {
            throw new ServiceException(AuthExceptionMsg.USER_INFO_NOT_EXIST);
        }
        // TODO 查询用户角色
        // TODO 查询用户权限
        if (RequestHelper.isSuperAdmin()) {
            userInfoVo.setRoles(CollectionUtil.newHashSet("superAdmin"));
            userInfoVo.setPermissions(CollectionUtil.newHashSet("*:*:*"));
        }
        userInfoVo.setUser(manageUserInfo);
        return userInfoVo;
    }

    /**
     * 根据用户ID获取用户信息
     * @param userId
     * @return
     */
    @Override
    public ManageUserInfo getUserInfoByUserId(Long userId) {
        return manageUserInfoMapper.selectById(userId);
    }

    /**
     * 验证邮箱是否存在
     * @param info 用户信息
     * @return
     */
    @Override
    public boolean checkEmailUnique(ManageUserInfo info) {
        boolean exists = manageUserInfoMapper.exists(new LambdaQueryWrapper<>(ManageUserInfo.class)
                .eq(ManageUserInfo::getEmail, info.getEmail())
                .ne(ObjectUtil.isNotBlank(info.getId()), ManageUserInfo::getId, info.getId()));
        return !exists;
    }

    /**
     * 验证手机号码是否存在
     * @param info 用户信息
     * @return
     */
    @Override
    public boolean checkPhoneUnique(ManageUserInfo info) {
        boolean exists = manageUserInfoMapper.exists(new LambdaQueryChainWrapper<>(ManageUserInfo.class)
                .eq(ManageUserInfo::getPhone, info.getPhone())
                .ne(ObjectUtil.isNotBlank(info.getId()), ManageUserInfo::getId, info.getId()));
        return !exists;
    }
}
